home *** CD-ROM | disk | FTP | other *** search
/ Resource Library: Multimedia / Resource Library: Multimedia.iso / utils / sound / convrtr / amiga / amisox_w / wav.c < prev   
Encoding:
C/C++ Source or Header  |  1992-05-12  |  4.8 KB  |  192 lines

  1. /*
  2.  * April 15, 1992
  3.  * Copyright 1992 Rick Richardson
  4.  * Copyright 1991 Lance Norskog And Sundry Contributors
  5.  * This source code is freely redistributable and may be used for
  6.  * any purpose.  This copyright notice must be maintained. 
  7.  * Lance Norskog And Sundry Contributors are not responsible for 
  8.  * the consequences of using this software.
  9.  */
  10.  
  11. /*
  12.  * Windows 3.0 .wav format driver
  13.  */
  14.  
  15. #include "st.h"
  16.  
  17. /* Private data for .wav file */
  18. typedef struct wavstuff {
  19.       long     samples;
  20. } *wav_t;
  21.  
  22. extern float volume, amplitude;
  23. extern int summary, verbose;
  24.  
  25. /*
  26.  * Do anything required before you start reading samples.
  27.  * Read file header. 
  28.  *    Find out sampling rate, 
  29.  *    size and style of samples, 
  30.  *    mono/stereo/quad.
  31.  */
  32. wavstartread(ft) 
  33. ft_t ft;
  34. {
  35.       wav_t   wav = (wav_t) ft->priv;
  36.       char    magic[4];
  37.       long    len;
  38.  
  39.       /* If you need to seek around the input file. */
  40.       if (0 && ! ft->seekable)
  41.               fail(".wav input file must be a file, not a pipe");
  42.  
  43.       fread(magic, 4, 1, ft->fp);
  44.       if (strncmp("RIFF", magic, 4))
  45.               fail("Not a RIFF file");
  46.  
  47.       len = rllong(ft);
  48.  
  49.       fread(magic, 4, 1, ft->fp);
  50.       if (strncmp("WAVE", magic, 4))
  51.               fail("Not a WAVE file");
  52.  
  53.       fread(magic, 4, 1, ft->fp);
  54.       if (strncmp("fmt ", magic, 4))
  55.               fail("Missing fmt spec");
  56.  
  57.       len = rllong(ft);
  58.       switch (rlshort(ft))
  59.       {
  60.       case 1:         ft->info.style = UNSIGNED; break;
  61.       default:        fail("Don't understand format");
  62.       }
  63.       ft->info.channels = rlshort(ft);
  64.       ft->info.rate = rllong(ft);
  65.       rllong(ft);     /* Average bytes/second */
  66.       rlshort(ft);    /* Block align */
  67.       switch (rlshort(ft))
  68.       {
  69.       case 8:         ft->info.size = BYTE; break;
  70.       case 16:        ft->info.size = WORD; break;
  71.       case 32:        ft->info.size = LONG; break;
  72.       default:        fail("Don't understand size");
  73.       }
  74.       len -= 16;
  75.       while (len) getc(ft->fp);
  76.  
  77.       fread(magic, 4, 1, ft->fp);
  78.       if (strncmp("data", magic, 4))
  79.               fail("Missing data portion");
  80.  
  81.       wav->samples = rllong(ft);
  82. }
  83.  
  84. /*
  85.  * Read up to len samples from file.
  86.  * Convert to signed longs.
  87.  * Place in buf[].
  88.  * Return number of samples read.
  89.  */
  90.  
  91. wavread(ft, buf, len) 
  92. ft_t ft;
  93. long *buf, len;
  94. {
  95.       wav_t   wav = (wav_t) ft->priv;
  96.       int     done;
  97.  
  98.       if (len > wav->samples) len = wav->samples;
  99.       if (len == 0) return 0;
  100.       done = rawread(ft, buf, len);
  101.       wav->samples -= len;
  102.       return done;
  103. }
  104.  
  105. /*
  106.  * Do anything required when you stop reading samples.  
  107.  * Don't close input file! 
  108.  */
  109. wavstopread(ft) 
  110. ft_t ft;
  111. {
  112. }
  113.  
  114. wavstartwrite(ft) 
  115. ft_t ft;
  116. {
  117.       wav_t   wav = (wav_t) ft->priv;
  118.       int     littlendian = 0;
  119.       char    *endptr;
  120.  
  121.       if (! ft->seekable)
  122.               fail("Output .wav file must be a file, not a pipe");
  123.  
  124.       endptr = (char *) &littlendian;
  125.       *endptr = 1;
  126.       if (!littlendian) ft->swap = 1;
  127.  
  128.       wav->samples = 0;
  129.       wavwritehdr(ft);
  130. }
  131.  
  132. wavwritehdr(ft) 
  133. ft_t ft;
  134. {
  135.       wav_t   wav = (wav_t) ft->priv;
  136.       int     samsize;
  137.       long    datasize;
  138.  
  139.       switch (ft->info.size)
  140.       {
  141.       case BYTE:      samsize = 8; break;
  142.       case WORD:      samsize = 16; break;
  143.       default:
  144.       case LONG:      ft->info.size = LONG; samsize = 32; break;
  145.       }
  146.       ft->info.style = UNSIGNED;
  147.  
  148.       datasize = samsize/8 * ft->info.channels * wav->samples;
  149.  
  150.       fputs("RIFF", ft->fp);
  151.       wllong(ft, datasize + 8+16+12); /* Waveform chunk size: FIXUP(4) */
  152.       fputs("WAVE", ft->fp);
  153.       fputs("fmt ", ft->fp);
  154.       wllong(ft, (long)16);                 /* fmt chunk size */
  155.       wlshort(ft, 1);                 /* FormatTag: WAVE_FORMAT_PCM */
  156.       wlshort(ft, ft->info.channels);
  157.       wllong(ft, (long)ft->info.rate);      /* SamplesPerSec */
  158.                                       /* Average Bytes/sec */
  159.       wllong(ft,         ((long)ft->info.rate * ft->info.channels * samsize + 7) / 8 );
  160.                                       /* nBlockAlign */
  161.       wlshort(ft, (ft->info.channels * samsize + 7) / 8);
  162.       wlshort(ft, samsize);           /* BitsPerSample */
  163.       
  164.       fputs("data", ft->fp);
  165.       wllong(ft, datasize);           /* data chunk size: FIXUP(40) */
  166. }
  167.  
  168. wavwrite(ft, buf, len) 
  169. ft_t ft;
  170. long *buf, len;
  171. {
  172.       wav_t   wav = (wav_t) ft->priv;
  173.  
  174.       wav->samples += len * ft->info.size;
  175.       rawwrite(ft, buf, len);
  176. }
  177. void
  178. wavstopwrite(ft) 
  179. ft_t ft;
  180. {
  181.       /* All samples are already written out. */
  182.       /* If file header needs fixing up, for example it needs the */
  183.       /* the number of samples in a field, seek back and write them here. */
  184.       wav_t   wav = (wav_t) ft->priv;
  185.  
  186.       if (!ft->seekable)
  187.               return;
  188.       if (fseek(ft->fp, 0L, 0) != 0)
  189.               fail("Can't rewind output file to rewrite .wav header.");
  190.       wavwritehdr(ft);
  191. }
  192.